import java.util.Timer;
import java.util.concurrent.PriorityBlockingQueue;

class MyTask implements Comparable<MyTask>{//表示一个任务
    public Runnable runnable;//任务
    public long time;//多长时间后开始执行
    @Override
    public int compareTo(MyTask o){//定义比较方法
        return (int)(this.time-o.time);
    }
    public MyTask(Runnable runnable,long delay){//
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;//当前时间加上delay才是开始执行任务的时间
    }
}
class Mytimer{//具体的实现
    private PriorityBlockingQueue<MyTask> priorityBlockingQueue=new PriorityBlockingQueue<>();//java库提供的优先级队列
    Object locker=new Object();//加锁的对象
    public void schedule(Runnable runnable,long delay){//schedule方法的实现
        MyTask myTask=new MyTask(runnable,delay);//通过传入的参数来创建mytask线程,也就是要执行的任务
        priorityBlockingQueue.put(myTask);//把任务放入带有优先级的阻塞队列中,队列会已依据compareto方法来对任务实现按照开始时间排序
        synchronized (locker){
            locker.notify();//在插入新的任务时,解除线程的wait,防止插入更加早的任务,而线程还在等待,不执行
        }
    }
    public Mytimer(){//构造方法,使其在new的时候就开始线程
        Thread thread=new Thread(()->{//创建执行任务的线程
            while (true){
                try {
                   synchronized (locker){//加锁,因为wait要使用
                       MyTask myTask=priorityBlockingQueue.take();//把开始时间最早的线程拿出来,看看时间到了没
                       long curtime=System.currentTimeMillis();//获取当前系统时间,为了于最早的任务开始时间对比
                       if(myTask.time<=curtime){//时间符合,可以执行
                           myTask.runnable.run();//执行传入的任务
                       }else {//时间还未到,等待
                           priorityBlockingQueue.put(myTask);//把拿出的任务放回队列中,因为还没到执行时间
                           locker.wait(myTask.time-curtime);//等待两时间之差,即是任务开始时间,当又schedule,插入新的任务是被唤醒
                       }
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();//启动线程
    }
}
public class Main {
    public static void main(String[] args) {
        Mytimer mytimer=new Mytimer();
        //Timer timer=new Timer();//java库提供的Timer类
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 5");
            }
        },5000);
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 4");
            }
        },4000);
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 3");
            }
        },3000);
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 2");
            }
        },2000);
        mytimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello 1");
            }
        },1000);
    }
}